import { ApiOutlined, DownOutlined, FolderOpenOutlined, FolderOutlined } from "@ant-design/icons";
import { Button, Card, Tree } from "antd";
import { useEffect, useState } from "react";
import OpenModal from "./OpenModal";
import { MethodWithServiceInfo, readProtoDesc } from "@linksaas-minapp/grpc-proxy-api";
import type { DataNode } from 'antd/es/tree'
import type { GrpcServerInfo } from "@linksaas-minapp/api/extra_info"
import { getMinAppInfo } from "@linksaas-minapp/api";

type ExDataNode = DataNode & {
    method?: MethodWithServiceInfo;
};

export interface ApiTreePanelProps {
    grpcApiId: string;
    onChange: (newGrpcApiId: string, grpcInfo: GrpcServerInfo) => void;
    curMethodList: MethodWithServiceInfo[];
    onSelect: (method: MethodWithServiceInfo) => void;
}

function ApiTreePanel(props: ApiTreePanelProps) {
    const [showOpenModal, setShowOpenModal] = useState(false);
    const [treeData, setTreeData] = useState<ExDataNode[]>([]);

    const loadApiTree = async () => {
        if (props.grpcApiId == "") {
            return;
        }
        let svcInfoList = await readProtoDesc(props.grpcApiId);
        svcInfoList = svcInfoList.sort((a, b) => a.serviceName.localeCompare(b.serviceName));
        svcInfoList.forEach(svc => {
            svc.methodList = svc.methodList.sort((a, b) => a.methodName.localeCompare(b.methodName));
        });
        const tmpTree: ExDataNode[] = [];
        for (const svcInfo of svcInfoList) {
            const parts = svcInfo.serviceName.split(".")
            const svcNode: ExDataNode = {
                title: parts[parts.length - 1],
                key: svcInfo.serviceName,
                icon: <FolderOutlined />,
                selectable: false,
                checkable: false,
                children: [],
            }
            for (const methodInfo of svcInfo.methodList) {
                const key = `${svcInfo.serviceName}.${methodInfo.methodName}`;
                svcNode.children?.push({
                    title: methodInfo.methodName,
                    key: key,
                    icon: <ApiOutlined />,
                    selectable: true,
                    checkable: false,
                    isLeaf: true,
                    method: {
                        serviceName: svcInfo.serviceName,
                        method: methodInfo,
                    },
                } as ExDataNode);
            }
            tmpTree.push(svcNode);
        }
        setTreeData(tmpTree);
    };

    useEffect(() => {
        loadApiTree();
    }, [props.grpcApiId]);


    useEffect(()=>{
        const minAppInfo = getMinAppInfo();
        if(minAppInfo != undefined && minAppInfo.extraInfo != undefined && minAppInfo.extraInfo.length > 0){
            setShowOpenModal(true);
        }
    },[]);

    return (
        <Card title="Api接口" bodyStyle={{ height: "calc(100vh - 60px)", padding: "0px 0px", overflowY: "auto" }} bordered={false}
            extra={
                <Button type="link" icon={<FolderOpenOutlined />}
                    onClick={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        setShowOpenModal(true);
                    }} />
            }>
            <Tree showIcon defaultExpandAll multiple
                switcherIcon={<DownOutlined />}
                treeData={treeData} onSelect={(_, info) => {
                    if (info.node.method !== undefined) {
                        props.onSelect(info.node.method);
                    }
                }}
                selectedKeys={props.curMethodList.map(item => `${item.serviceName}.${item.method.methodName}`)} />
            {showOpenModal == true && (
                <OpenModal onCancel={() => setShowOpenModal(false)} onOk={(newGrpcApiId, newGrpcInfo) => {
                    props.onChange(newGrpcApiId, newGrpcInfo);
                    setShowOpenModal(false);
                }} />
            )}
        </Card>
    );
}

export default ApiTreePanel